package sunyu.controller.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.Subject;
import org.nutz.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import sunyu.tools.encrypt.EncryptTools;

import javax.annotation.Resource;
import java.util.Collection;

/**
 * Created by 孙宇
 */
@Controller
@RequestMapping("/shiro")
public class ShiroController {

    private static final Logger logger = LoggerFactory.getLogger(Thread.currentThread().getClass());

    @Resource(name = "encryptTools")
    private EncryptTools encryptTools;

    @Resource(name = "shiroSessionDAO")
    private SessionDAO sessionDAO;

    /**
     * 跳转到未经许可页面
     *
     * @return
     */
    @RequestMapping(value = "/unauthorized")
    public String unauthorized() {
        return "/unauthorized";
    }

    /**
     * 退出登录
     *
     * @return
     */
    @RequestMapping(value = "/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "/index";
    }

    /**
     * 跳转到登录页面
     *
     * @return
     */
    @RequestMapping(value = "/login", method = {RequestMethod.GET})
    public String login() {
        return "/shiro/login";
    }

    /**
     * 登录
     *
     * @param loginName
     * @param loginPassword
     * @param model
     *
     * @return
     */
    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public String login(String loginName,
                        String loginPassword,
                        Model model) {
        String msg;
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginName, encryptTools.md5(loginPassword));
        try {
            subject.login(token);
            if (subject.isAuthenticated()) {
                return "redirect:/shiro/main";
            }
        } catch (IncorrectCredentialsException e) {
            msg = "[" + token.getPrincipal() + "]登录密码错误！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (ExcessiveAttemptsException e) {
            msg = "登录失败次数过多！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (LockedAccountException e) {
            msg = "[" + token.getPrincipal() + "]帐号已被锁定！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (DisabledAccountException e) {
            msg = "[" + token.getPrincipal() + "]帐号已被禁用！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (ExpiredCredentialsException e) {
            msg = "[" + token.getPrincipal() + "]帐号已过期！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (UnknownAccountException e) {
            msg = "[" + token.getPrincipal() + "]帐号不存在！";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        } catch (UnauthorizedException e) {
            msg = "您没有得到相应的授权！[" + e.getMessage() + "]";
            model.addAttribute("errMsg", msg);
            logger.error(msg);
        }
        return "/shiro/login";
    }

    /**
     * 跳转到后台管理main页面
     *
     * @return
     */
    @RequestMapping(value = "/main", method = {RequestMethod.GET})
    @RequiresAuthentication//验证是否登录，等同于subject.isAuthenticated()
    @RequiresPermissions(value = {"shiro:main"}, logical = Logical.AND)//验证是否有权限
    public String main() {
        return "/shiro/main";
    }

    /**
     * 所有活动session
     *
     * @return
     */
    @RequestMapping(value = "/activeSessions", method = {RequestMethod.GET})
    @RequiresAuthentication
    @ResponseBody
    public Collection<Session> activeSessions() {
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        System.out.println("总数:" + sessions.size());
        for (Session session : sessions) {
            System.out.println("SessionId:" + session.getId());
            System.out.println("登录ip:" + session.getHost());
            System.out.println("最后操作日期:" + session.getLastAccessTime());
            for (Object key : session.getAttributeKeys()) {
                System.out.println(key + ":" + Json.toJson(session.getAttribute(key)));
            }
        }
        return sessions;
    }

}
